//
//  MapConvertUtil.m
//  amap_flutter_map
//
//  Created by lly on 2020/10/30.
//

#import "FlutterUtil.h"
#import "MapConvertUtil.h"
#import "MapJsonUtils.h"
#import "FlutterMapCameraPosition.h"
#import "FlutterMapControllerProtocol.h"
#import "FlutterEnum.h"

@implementation FlutterUtil

+ (UIImage*)imageFromRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar iconData:(NSArray*)iconData {
    UIImage* image;
    if ([iconData.firstObject isEqualToString:@"defaultMarker"]) {
        image = [UIImage imageNamed:[registrar lookupKeyForAsset:@"packages/amap_flutter_map/res/marker_default.png"]];//默认的图片资源
        CGFloat screenScale = [[UIScreen mainScreen] scale];
        image = [MapConvertUtil scaleImage:image param:[NSNumber numberWithFloat:screenScale]];
        //添加默认图片
    } else if ([iconData.firstObject isEqualToString:@"fromAsset"]) {
        if (iconData.count == 2) {
            NSString *path = [registrar lookupKeyForAsset:iconData[1]];
            image = [UIImage imageNamed:path];
            CGFloat screenScale = [[UIScreen mainScreen] scale];
            image = [MapConvertUtil scaleImage:image param:[NSNumber numberWithFloat:screenScale]];
        }
    } else if ([iconData.firstObject isEqualToString:@"fromAssetImage"]) {
        if (iconData.count == 3) {
            NSString *path = [registrar lookupKeyForAsset:iconData[1]];
            image = [UIImage imageNamed:path];
            NSNumber* scaleParam = iconData[2];
            image = [MapConvertUtil scaleImage:image param:scaleParam];
        } else {
            NSString* error =
            [NSString stringWithFormat:@"'fromAssetImage' should have exactly 3 arguments. Got: %lu",
             (unsigned long)iconData.count];
            NSException* exception = [NSException exceptionWithName:@"InvalidBitmapDescriptor"
                                                             reason:error
                                                           userInfo:nil];
            @throw exception;
        }
    } else if ([iconData[0] isEqualToString:@"fromBytes"]) {
        if (iconData.count == 2) {
            @try {
                FlutterStandardTypedData* byteData = iconData[1];
                CGFloat screenScale = [[UIScreen mainScreen] scale];
                image = [UIImage imageWithData:[byteData data] scale:screenScale];
            } @catch (NSException* exception) {
                @throw [NSException exceptionWithName:@"InvalidByteDescriptor"
                                               reason:@"Unable to interpret bytes as a valid image."
                                             userInfo:nil];
            }
        } else {
            NSString* error = [NSString
                               stringWithFormat:@"fromBytes should have exactly one argument, the bytes. Got: %lu",
                               (unsigned long)iconData.count];
            NSException* exception = [NSException exceptionWithName:@"InvalidByteDescriptor"
                                                             reason:error
                                                           userInfo:nil];
            @throw exception;
        }
    }
    
    return image;
}

////
////  MAMapView+Flutter.m
////  amap_flutter_map
////
////  Created by lly on 2020/10/30.
////
//
//#import "MAMapView+Flutter.h"
//#import "FlutterMapCameraPosition.h"
//#import "MapConvertUtil.h"
//
//@implementation MAMapView (Flutter)
//
////- (void)setCameraPosition:(FlutterMapCameraPosition *)cameraPosition animated:(BOOL)animated duration:(CFTimeInterval)duration {
////    if (cameraPosition == nil) {
////        return;
////    }
////    MAMapStatus *mapStatus = [MAMapStatus statusWithCenterCoordinate:cameraPosition.target
////                                                           zoomLevel:cameraPosition.zoom
////                                                      rotationDegree:cameraPosition.bearing
////                                                        cameraDegree:cameraPosition.tilt
////                                                        screenAnchor:self.screenAnchor];
////    [self setMapStatus:mapStatus animated:animated duration:duration];
////}
////
////- (FlutterMapCameraPosition *)getCurrentCameraPosition {
////    FlutterMapCameraPosition *position = [[FlutterMapCameraPosition alloc] init];
////    position.target = self.centerCoordinate;
////    position.zoom = self.zoomLevel;
////    position.bearing = self.rotationDegree;
////    position.tilt = self.cameraDegree;
////    return position;
////}
////
+ (void)setCameraUpdateDict:(NSDictionary *)updateDict
              mapController: (id<FlutterMapControllerProtocol>)mapController  {
    if (updateDict == nil || updateDict.count == 0) {
        return;
    }
    BOOL animated;
    if ([updateDict[@"animated"] isKindOfClass:[NSNull class]]) {
        animated = NO;
    } else {
        animated = [updateDict[@"animated"] boolValue];
    }
    double duration;
    if ([updateDict[@"duration"] isKindOfClass:[NSNull class]]) {
        duration = 0;
    } else {
        duration = [updateDict[@"duration"] doubleValue]/1000.0;
    }
    NSArray *cameraUpdate = updateDict[@"cameraUpdate"];
    //后面的操作时数组，第一个是操作符，后面才是真的参数；
    NSAssert(cameraUpdate.count >= 1, @"cameraUpdate 参数错误");
    NSString *operation = cameraUpdate.firstObject;
    if ([operation isEqualToString:@"newCameraPosition"] && cameraUpdate.count == 2) {//按照cameraPositon移动
        FlutterMapCameraPosition *newCameraPosition = [MapJsonUtils modelFromDict:cameraUpdate[1] modelClass:[FlutterMapCameraPosition class]];
        [mapController setCenterPoint:newCameraPosition.target animated:animated];
        [mapController setZoomLevel:newCameraPosition.zoom animated:animated];

//        [self setCameraPosition:newCameraPosition animated:animated duration:duration];
    } else if ([operation isEqualToString:@"newLatLng"] && cameraUpdate.count == 2) {//只移动屏幕中心点
        CLLocationCoordinate2D position = [MapConvertUtil coordinateFromArray:cameraUpdate[1]];
        [mapController setCenterPoint:position animated:animated];
//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.centerCoordinate = position;
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    } else if ([operation isEqualToString:@"newLatLngBounds"] && cameraUpdate.count == 3) {//设置视图的显示范围和边界
//        TODO: 这里没有使用参数duration
        NSArray *array = cameraUpdate[1];
        NSAssert((array && [array isKindOfClass:[NSArray class]] && array.count == 2), @"解析mapRect的参数有误");
        CLLocationCoordinate2D southwest = [MapConvertUtil coordinateFromArray:array[0]];
        CLLocationCoordinate2D northeast = [MapConvertUtil coordinateFromArray:array[1]];
        CGRect rect = [mapController convertToMapRectWithSouthwest:southwest northeast:northeast];

//        MAMapRect boundRect = [MapConvertUtil mapRectFromArray:cameraUpdate[1]];
        double padding = [cameraUpdate[2] doubleValue];
        UIEdgeInsets inset = UIEdgeInsetsMake(padding, padding, padding, padding);
        [mapController setVisibleMapRect:rect edgePadding:inset animated:animated];

//        [mapController setVisibleMapRect:CGRectMake(boundRect.origin.x,
//                                                    boundRect.origin.y,
//                                                    boundRect.size.width,
//                                                    boundRect.size.height)
//                             edgePadding:inset
//                                animated:animated];
    }  else if ([operation isEqualToString:@"newLatLngBoundsWithEdgeInsets"] && cameraUpdate.count == 6) {//设置视图的显示范围和边界
        //        TODO: 这里没有使用参数duration
        NSArray *array = cameraUpdate[1];
        NSAssert((array && [array isKindOfClass:[NSArray class]] && array.count == 2), @"解析mapRect的参数有误");
        CLLocationCoordinate2D southwest = [MapConvertUtil coordinateFromArray:array[0]];
        CLLocationCoordinate2D northeast = [MapConvertUtil coordinateFromArray:array[1]];
        CGRect rect = [mapController convertToMapRectWithSouthwest:southwest northeast:northeast];

        //        MAMapRect boundRect = [MapConvertUtil mapRectFromArray:cameraUpdate[1]];
        double left = [cameraUpdate[2] doubleValue];
        double top = [cameraUpdate[3] doubleValue];
        double right = [cameraUpdate[4] doubleValue];
        double bottom = [cameraUpdate[5] doubleValue];

        UIEdgeInsets inset = UIEdgeInsetsMake(top, left, bottom, right);
        [mapController setVisibleMapRect:rect edgePadding:inset animated:animated];

        //        [mapController setVisibleMapRect:CGRectMake(boundRect.origin.x,
        //                                                    boundRect.origin.y,
        //                                                    boundRect.size.width,
        //                                                    boundRect.size.height)
        //                             edgePadding:inset
        //                                animated:animated];
    }  else if ([operation isEqualToString:@"newLatLngZoom"] && cameraUpdate.count == 3) {//设置地图中心点和zoomLevel
        CLLocationCoordinate2D position = [MapConvertUtil coordinateFromArray:cameraUpdate[1]];
        CGFloat zoomLevel = [cameraUpdate[2] floatValue];
        [mapController setCenterPoint:position animated:animated];
        [mapController setZoomLevel:zoomLevel animated:animated];

//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.centerCoordinate = position;
//        currentStatus.zoomLevel = zoomLevel;
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    } else if ([operation isEqualToString:@"scrollBy"] && cameraUpdate.count == 3) {//按照屏幕像素点移动
        CGPoint pixelPointOffset = CGPointMake([cameraUpdate[1] doubleValue], [cameraUpdate[2] doubleValue]);
        CGPoint center = mapController.flutterView.center;
        CGPoint updateCenter = CGPointMake(center.x + pixelPointOffset.x/[UIScreen mainScreen].scale, center.y + pixelPointOffset.y/[UIScreen mainScreen].scale);
        CLLocationCoordinate2D centerCoord = [mapController convertToCoordinate:updateCenter from:mapController.flutterView];
        [mapController setCenterPoint:centerCoord animated:animated];

//        CGPoint updateCenter = CGPointMake(self.center.x + pixelPointOffset.x/[UIScreen mainScreen].scale, self.center.y + pixelPointOffset.y/[UIScreen mainScreen].scale);
//        CLLocationCoordinate2D centerCoord = [self convertPoint:updateCenter toCoordinateFromView:self];
//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.centerCoordinate = centerCoord;
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    } else if ([operation isEqualToString:@"zoomIn"]) {
        [mapController setZoomLevel:mapController.zoomLevel + 1 animated:animated];
//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.zoomLevel = currentStatus.zoomLevel + 1;
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    } else if ([operation isEqualToString:@"zoomOut"]) {
        [mapController setZoomLevel:mapController.zoomLevel - 1 animated:animated];

//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.zoomLevel = currentStatus.zoomLevel - 1;
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    } else if ([operation isEqualToString:@"zoomTo"] && cameraUpdate.count == 2) {
        [mapController setZoomLevel:[cameraUpdate[1] doubleValue] animated:animated];

//        MAMapStatus *currentStatus = [self getMapStatus];
//        currentStatus.zoomLevel = [cameraUpdate[1] doubleValue];
//        [self setMapStatus:currentStatus animated:animated duration:duration];
    }
}


+ (void)updateMapViewOption:(NSDictionary *)dict withRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
              mapController: (id<FlutterMapControllerProtocol>)mapController
                     isInit: (BOOL)isInit {
    if ([dict isKindOfClass:[NSDictionary class]] == NO || dict == nil || dict.count == 0) {
        return;
    }
//    //地图类型
//    NSNumber *mapType = dict[@"mapType"];
//    if (mapType) {
//        option.mapType = mapType.integerValue;
//    }
//    NSDictionary *customStyleOptions = dict[@"customStyleOptions"];
//    if (customStyleOptions) {
//        BOOL customMapStyleEnabled = [customStyleOptions[@"enabled"] boolValue];
//        option.customMapStyleEnabled = customMapStyleEnabled;
//        if (customMapStyleEnabled) {
//            MAMapCustomStyleOptions *styleOption = [[MAMapCustomStyleOptions alloc] init];
//            styleOption.styleData = ((FlutterStandardTypedData*)customStyleOptions[@"styleData"]).data;
//            styleOption.styleExtraData = ((FlutterStandardTypedData*)customStyleOptions[@"styleExtraData"]).data;
//            option.styleOption = styleOption;
//        }
//    }
//
    NSDictionary *locationStyleDict = dict[@"myLocationStyle"];
    if (locationStyleDict) {
        BOOL showUserLocation = [locationStyleDict[@"enabled"] boolValue];
        [mapController showsUserLocation:showUserLocation];
//        option.showsUserLocation = showUserLocation;
        if (showUserLocation) {
            [mapController setUserTrackingMode:UserTrackingModeNone];
//            option.userTrackingMode = UserTrackingModeNone;//强制设置为非追随模式，追随模式后续在demo中，使用自定义定位样式实现

//            if (locationStyleDict[@"circleFillColor"] != nil
//                || locationStyleDict[@"circleStrokeColor"] != nil
//                || locationStyleDict[@"circleStrokeWidth"] != nil
//                || locationStyleDict[@"icon"] != nil) {//自定义样式有不为空的属性时，才启动自定义的样式设置
//                MAUserLocationRepresentation *locationStyle = [[MAUserLocationRepresentation alloc] init];
//                if (locationStyleDict[@"circleFillColor"]) {
//                    locationStyle.fillColor = [MapConvertUtil colorFromNumber:locationStyleDict[@"circleFillColor"]];
//                }
//                if (locationStyleDict[@"circleStrokeColor"]) {
//                    locationStyle.strokeColor = [MapConvertUtil colorFromNumber:locationStyleDict[@"circleStrokeColor"]];
//                }
//                if (locationStyleDict[@"circleStrokeWidth"]) {
//                    locationStyle.lineWidth = [locationStyleDict[@"circleStrokeWidth"] doubleValue];
//                }
//                if (locationStyleDict[@"icon"]) {
//                    locationStyle.image = [FlutterUtil imageFromRegistrar:registrar iconData:locationStyleDict[@"icon"]];
//                }
//                option.locationStyle = locationStyle;
//            }
        }
    }

    ///地图锚点
    NSArray *screenAnchor = dict[@"screenAnchor"];
    if (screenAnchor) {
        CGPoint anchorPoint = [MapConvertUtil pointFromArray:screenAnchor];
        [mapController setScreenAnchor:anchorPoint];
    }

    //缩放级别范围
//    NSArray* zoomData = dict[@"minMaxZoomPreference"];
//    if (zoomData) {
//        CGFloat minZoom = (zoomData[0] == [NSNull null]) ? 3.0 : [zoomData[0] doubleValue];
//        option.minZoomLevel = minZoom;
//        CGFloat maxZoom = (zoomData[1] == [NSNull null]) ? 20.0 : [zoomData[1] doubleValue];
//        option.maxZoomLevel = maxZoom;
//    }
    NSArray *limitBounds = dict[@"limitBounds"];
    if (limitBounds) {
        NSArray *array = limitBounds;
        NSAssert((array && [array isKindOfClass:[NSArray class]] && array.count == 2), @"解析mapRect的参数有误");
        CLLocationCoordinate2D southwest = [MapConvertUtil coordinateFromArray:array[0]];
        CLLocationCoordinate2D northeast = [MapConvertUtil coordinateFromArray:array[1]];
        CGRect rect = [mapController convertToMapRectWithSouthwest:southwest northeast:northeast];
        if (isInit == TRUE) {
            [mapController initVisibleMapRect:rect
                                  edgePadding:UIEdgeInsetsMake(0, 0, 0, 0)
                                     animated:FALSE];
        } else {
            [mapController setVisibleMapRect:rect
                                  edgePadding:UIEdgeInsetsMake(0, 0, 0, 0)
                                     animated: TRUE];
        }

//        MAMapRect limitRect = [MapConvertUtil mapRectFromArray:limitBounds];
//        [mapController setVisibleMapRect: CGRectMake(limitRect.origin.x, limitRect.origin.y, limitRect.size.width, limitRect.size.height)
//                             edgePadding: UIEdgeInsetsMake(0, 0, 0, 0)
//                                animated: isInit ? FALSE : TRUE];
    }
//    //显示路况开关
//    NSNumber *showTraffic = dict[@"trafficEnabled"];
//    if (showTraffic) {
//        option.showTraffic = [showTraffic boolValue];
//    }
//    // 地图poi是否允许点击
//    NSNumber *touchPOIEnable = dict[@"touchPoiEnabled"];
//    if (touchPOIEnable) {
//        option.touchPOIEnabled = [touchPOIEnable boolValue];
//    }
//    //是否显示3D建筑物
//    NSNumber *showBuilding = dict[@"buildingsEnabled"];
//    if (showBuilding) {
//        option.showsBuildings = [showBuilding boolValue];
//    }
//    //是否显示底图文字标注
//    NSNumber *showLable = dict[@"labelsEnabled"];
//    if (showLable) {
//        option.showsLabels = [showLable boolValue];
//    }
//    //是否显示指南针
//    NSNumber *showCompass = dict[@"compassEnabled"];
//    if (showCompass) {
//        option.showsCompass = [showCompass boolValue];
//    }
//    //是否显示比例尺
//    NSNumber *showScale = dict[@"scaleEnabled"];
//    if (showScale) {
//        option.showsScale = [showScale boolValue];
//    }
//    //是否支持缩放手势
//    NSNumber *zoomEnable = dict[@"zoomGesturesEnabled"];
//    if (zoomEnable) {
//        option.zoomEnabled = [zoomEnable boolValue];
//    }
//    //是否支持滑动手势
//    NSNumber *scrollEnable = dict[@"scrollGesturesEnabled"];
//    if (scrollEnable) {
//        option.scrollEnabled = [scrollEnable boolValue];
//    }
//    //是否支持旋转手势
//    NSNumber *rotateEnable = dict[@"rotateGesturesEnabled"];
//    if (rotateEnable) {
//        option.rotateEnabled = [rotateEnable boolValue];
//    }
//    //是否支持仰角手势
//    NSNumber *rotateCameraEnable = dict[@"tiltGesturesEnabled"];
//    if (rotateCameraEnable) {
//        option.rotateCameraEnabled = [rotateCameraEnable boolValue];
//    }
}

//@end


@end
